﻿using System;
using LAeMail.Infrastructure;
using System.Windows.Input;
using System.Windows;
using System.IO;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Diagnostics;

//TODO: Misc
//- Log to file
//- Duplicate Emails

//TODO: Update 
//Update Class
// - Read release notes
// - Get current version, new version, update URL
// - Use this in binding. 

namespace LAeMail.ViewModels
{
    public class MainWindowViewModel : WorkspaceViewModel
    {
        #region Private
        private const int TABSEND = 0;
        private const int TABSETTINGS = 1;
        private const int TABHELP = 2;
        private const int TABUPDATE = 3;

        private Logger logger = new Logger();
        #endregion

        #region Properties
        public WindowState CurrentWindowState
        {
            get { return Get(() => CurrentWindowState, WindowState.Normal); }
            set { Set(() => CurrentWindowState, value); }
        }

        public Uri HelpPage
        {
            get { return Get(() => HelpPage, new Uri(String.Format(@"{0}\Help\help.htm", Directory.GetCurrentDirectory()))); }
            set { Set(() => HelpPage, value); }
        }
        
        public int TabIndex
        {
            get { return Get(() => TabIndex); }
            set { Set(() => TabIndex, value); onTabIndexHandler(); }
        }

        public String Subject
        {
            get { return Get(() => Subject); }
            set { Set(() => Subject, value);}
        }

        public String BodyTextPath
        {
            get { return Get(() => BodyTextPath); }
            set { Set(() => BodyTextPath, value); }
        }

        public String RecipientListPath
        {
            get { return Get(() => RecipientListPath); }
            set { Set(() => RecipientListPath, value); }
        }

        public ObservableCollection<LogItem> Progress
        {
            get { return Get(() => Progress); }
            set { Set(() => Progress, value); }
        }

        public MailManager MailManager { get; set; }

        public String StartStop
        {
            get { return Get(() => StartStop, Properties.Resources.LABEL_Start); }
            set { Set(() => StartStop, value); }
        }

        public String SettingsServer
        {
            get { return Get(() => SettingsServer, Properties.Settings.Default.EmailServer); }
            set { Set(() => SettingsServer, value); Properties.Settings.Default.EmailServer = value; Properties.Settings.Default.Save(); }
        }

        public String SettingsPort
        {
            get { return Get(() => SettingsPort, Properties.Settings.Default.EmailPort); }
            set { Set(() => SettingsPort, value); Properties.Settings.Default.EmailPort = value; Properties.Settings.Default.Save(); }
        }

        public String SettingsSender
        {
            get { return Get(() => SettingsSender, Properties.Settings.Default.EmailSender); }
            set { Set(() => SettingsSender, value); Properties.Settings.Default.EmailSender = value; Properties.Settings.Default.Save(); }
        }

        public String SettingsFriendlyName
        {
            get { return Get(() => SettingsFriendlyName, Properties.Settings.Default.EmailFriendlyName); }
            set { Set(() => SettingsFriendlyName, value); Properties.Settings.Default.EmailFriendlyName = value; Properties.Settings.Default.Save(); }
        }

        public bool SettingsIsAnonymous
        {
            get { return Get(() => SettingsIsAnonymous, String.IsNullOrEmpty(Properties.Settings.Default.EmailUser)); }
            set { Set(() => SettingsIsAnonymous, value); if (value == true) { SettingsUser = String.Empty; SettingsPassword = String.Empty; } }
        }

        public String SettingsUser
        {
            get { return Get(() => SettingsUser, Properties.Settings.Default.EmailUser); }
            set { Set(() => SettingsUser, value); if (!String.IsNullOrEmpty(value)) SettingsIsAnonymous = false; Properties.Settings.Default.EmailUser = value; Properties.Settings.Default.Save(); }
        }

        public String SettingsPassword
        {
            get { return Get(() => SettingsPassword, Properties.Settings.Default.EmailPassword); }
            set { Set(() => SettingsPassword, value); if (!String.IsNullOrEmpty(value)) SettingsIsAnonymous = false; Properties.Settings.Default.EmailPassword = value; Properties.Settings.Default.Save(); }
        }

        public bool SettingsLogToFile
        {
            get { return Get(() => SettingsLogToFile, Properties.Settings.Default.LogToFile); }
            set { Set(() => SettingsLogToFile, value); Properties.Settings.Default.LogToFile = value; Properties.Settings.Default.Save(); logger.SetLogToFile(Properties.Settings.Default.LogToFile); }
        }

        public UpdateManager UpdateManager { get; set; }

        #endregion

        #region Commands
        public ICommand OnMinimize { get; set; }
        public ICommand StartCommand { get; set; }
        public ICommand FindBodyTextCommand { get; set; }
        public ICommand FindRecipientsCommand { get; set; }
        public ICommand OnUpdateLink { get; set; }
        #endregion

        #region Constructors
        public MainWindowViewModel()
        {
            base.DisplayName = Properties.Resources.LABEL_Title;
            OnMinimize = new RelayCommand(param => onMinimizeHandler());
            StartCommand = new RelayCommand(param => startHandler());
            FindBodyTextCommand = new RelayCommand(param => findBodyTextHandler());
            FindRecipientsCommand = new RelayCommand(param => findRecipientsHandler());
            OnUpdateLink = new RelayCommand(param => onUpdateLinkHandler());

            Subject = Properties.Settings.Default.Subject;
            BodyTextPath = Properties.Settings.Default.BodyTextPath;
            RecipientListPath = Properties.Settings.Default.RecipientListPath;

            Progress = new ObservableCollection<LogItem>();
            logger.SetLoggerList(Progress);
            logger.SetLogToFile(Properties.Settings.Default.LogToFile);

            MailManager = new MailManager(onMailQueueRunning, onMailQueueComplete, onNotify);
            UpdateManager = new UpdateManager(onUpdateManagerDone, onNotify);

            TabIndex = HaveSettings() ? TABSEND : TABSETTINGS;
            logger.Log(LogLevel.Info, String.Format(Properties.Resources.INFO_Welcome, UpdateManager.CurrentVersion));
        }
        #endregion

        #region Handlers
        private void onUpdateLinkHandler()
        {
            Process.Start(new ProcessStartInfo(UpdateManager.UpdateLink));
        }

        private void onMinimizeHandler()
        {
            CurrentWindowState = WindowState.Minimized;
        }

        private void onTabIndexHandler()
        {
        }

        private void onMailQueueRunning()
        {
            logger.Log(LogLevel.Info, Properties.Resources.INFO_ProcessingMailQueue);
            StartStop = Properties.Resources.LABEL_Stop;
        }

        private void onMailQueueComplete()
        {
            logger.Log(LogLevel.Info, Properties.Resources.INFO_ProcessingMailQueueDone);
            StartStop = Properties.Resources.LABEL_Start;
        }

        private void onUpdateManagerDone(bool updateAvailable)
        {
            UpdateManager.UpdateAvailable = updateAvailable;
            TabIndex = UpdateManager.UpdateAvailable ? TABUPDATE : TabIndex;
        }

        private void onNotify(LogLevel level, String notification)
        {
            logger.Log(level, notification);
        }

        private void startHandler()
        {
            if (MailManager.Running == false)
            {
                if (!HaveSettings())
                {
                    logger.Log(LogLevel.Error, Properties.Resources.ERROR_MissingSettings);
                    return;
                }

                if (MailManager.Load(Subject, BodyTextPath, RecipientListPath) == false)
                    return;

                Properties.Settings.Default.Subject = Subject;
                Properties.Settings.Default.BodyTextPath = BodyTextPath;
                Properties.Settings.Default.RecipientListPath = RecipientListPath;
                Properties.Settings.Default.Save();

                logger.Log(LogLevel.Info, Properties.Resources.INFO_LoadedOk);
                MailManager.Run();
            }
            else
            {
                MailManager.Cancel();
            }
        }

        private string getInitialDirectory(String path)
        {
            if (String.IsNullOrEmpty(path))
                return  Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            path = Path.GetDirectoryName(path);    

            if (Directory.Exists(path)==false)
                return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            return path;
        }

        private void findBodyTextHandler()
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog()
            {
                InitialDirectory = getInitialDirectory(BodyTextPath),
                Title = Properties.Resources.TITLE_BodyText,
                DefaultExt = ".txt",
                Filter = "Text files (*.txt)|*.txt|Web files (*.html,*.htm)|*.html;*.htm|All files (*.*)|*.*"
            };
 
            if (dlg.ShowDialog().GetValueOrDefault()==true)
            {
                Properties.Settings.Default.BodyTextPath = BodyTextPath = dlg.FileName;
                Properties.Settings.Default.Save();
            }
        }

        private void findRecipientsHandler()
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog()
            {
                InitialDirectory = getInitialDirectory(RecipientListPath),
                Title = Properties.Resources.TITLE_Recipients,
                DefaultExt = ".txt",
                Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"
            };

            if (dlg.ShowDialog().GetValueOrDefault() == true)
            {
                Properties.Settings.Default.RecipientListPath = RecipientListPath = dlg.FileName;
                Properties.Settings.Default.Save();
            }
        }
        #endregion

        #region Settings
        private bool HaveSettings()
        {
            if (String.IsNullOrEmpty(Properties.Settings.Default.EmailServer))
                return false;

            if (String.IsNullOrEmpty(Properties.Settings.Default.EmailPort))
                return false;

            if (String.IsNullOrEmpty(Properties.Settings.Default.EmailSender))
                return false;

            return true;
        }
        #endregion
    }
}
